package com.xiaou.es.demo;

import java.net.InetAddress;
import java.net.UnknownHostException;

import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.filter.Filter;
import org.elasticsearch.search.aggregations.bucket.filter.Filters;
import org.elasticsearch.search.aggregations.bucket.filter.FiltersAggregator;
import org.elasticsearch.search.aggregations.bucket.filter.FiltersAggregator.KeyedFilter;
import org.elasticsearch.search.aggregations.bucket.missing.Missing;
import org.elasticsearch.search.aggregations.bucket.range.Range;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.metrics.avg.Avg;
import org.elasticsearch.search.aggregations.metrics.cardinality.Cardinality;
import org.elasticsearch.search.aggregations.metrics.max.Max;
import org.elasticsearch.search.aggregations.metrics.min.Min;
import org.elasticsearch.search.aggregations.metrics.sum.Sum;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.Log4J2LoggerFactory;

/**
 * 聚合查询
 * @author xiaou
 * @date 2018年9月15日-下午2:54:34
 */
public class Query2 {
	private TransportClient client;
	private static InternalLogger log =Log4J2LoggerFactory.getInstance(EasyCrud.class);
	
	@SuppressWarnings("resource")
	@Before
	public void before() throws UnknownHostException {
		
		Settings settings = Settings.builder()
				.put("cluster.name", "myes")
				.build();
		
		client = new PreBuiltTransportClient(settings)
				.addTransportAddress(
						new TransportAddress(InetAddress.getByName("192.168.150.142"), 9300)
						);
	}
	
	@After
	public void after() {
		client.close();
	}
	
	// 聚合查询
	@Test
	public void test1() {
		AggregationBuilder aggMax = AggregationBuilders.max("max")
													.field("price");
		AggregationBuilder aggMin = AggregationBuilders.min("min")
													.field("price");
		AggregationBuilder aggAvg = AggregationBuilders.avg("avg")
													   .field("price");
		AggregationBuilder aggSum = AggregationBuilders.sum("sum")
														.field("price");
		AggregationBuilder aggCardinality = AggregationBuilders.cardinality("cardinality")
													.field("price");
		SearchResponse response = client.prepareSearch("xiaou")
										.addAggregation(aggMax)
										.addAggregation(aggMin)
										.addAggregation(aggAvg)
										.addAggregation(aggCardinality)
										.addAggregation(aggSum)
										.get();
		
		Max max = response.getAggregations().get("max");
		Min min = response.getAggregations().get("min");
		Avg avg = response.getAggregations().get("avg");
		Sum sum = response.getAggregations().get("sum");
		Cardinality cardinality = response.getAggregations().get("cardinality");
		
		log.info("最大值:"+max.getValue());
		log.info("最小值:"+min.getValue());
		log.info("平均值:"+avg.getValue());
		log.info("总和"+sum.getValueAsString());
		log.info("基数:"+cardinality.getValue());
	}

	// query string
	@Test
	public void test2() {
		// 常用词查询
		//QueryBuilder builder = QueryBuilders.commonTermsQuery("title", "java");
		//必须由带java的但不能有100的
		//QueryBuilder builder = QueryBuilders.queryStringQuery("+java -100");
		//或连接
		QueryBuilder builder = QueryBuilders.simpleQueryStringQuery("java 60");
		SearchResponse response = client.prepareSearch("xiaou").setQuery(builder).get();
		SearchHits hits = response.getHits();
		for (SearchHit hit : hits) {
			System.out.println(hit.getSourceAsString());
		}
	}
	
	// 组合查询1
	@Test
	public void test3() {
		
		QueryBuilder builder = QueryBuilders.boolQuery()
							   .must(QueryBuilders.matchQuery("price", 60))
							   .should(QueryBuilders.matchQuery("title", "php"))
							   .filter(QueryBuilders.queryStringQuery("php"));
							   
		
		SearchResponse response = client.prepareSearch("xiaou").setQuery(builder).get();
		
		SearchHits hits = response.getHits();
		for (SearchHit hit : hits) {
			System.out.println(hit.getSourceAsString());
		}
	}
	
	// 组合查询2 --constantscore 不计算分数
		@Test
		public void test4() {
			
			QueryBuilder builder = QueryBuilders.constantScoreQuery(QueryBuilders.boolQuery()
																	.must(QueryBuilders.matchQuery("price", 60)));
			
			SearchResponse response = client.prepareSearch("xiaou").setQuery(builder).get();
			
			SearchHits hits = response.getHits();
			for (SearchHit hit : hits) {
				System.out.println(hit.getSourceAsString());
			}
		}
	// 分组
		@Test
		public void test5() {
			
			AggregationBuilder aggregationBuilder = AggregationBuilders.terms("terms").field("price");
			SearchResponse response = client.prepareSearch("xiaou").addAggregation(aggregationBuilder).get();
			log.info(response.status().toString());
			Terms terms = response.getAggregations().get("terms");
			
			for(Terms.Bucket entry :terms.getBuckets()) {
				System.out.println(entry.getKey()+":"+entry.getDocCount());
			}
		}
	// filter 聚合
		@Test
		public void test6() {
			QueryBuilder termQuery = QueryBuilders.termQuery("price", 60);
			AggregationBuilder aggregationBuilder = AggregationBuilders.filter("filter", termQuery);
			SearchResponse response = client.prepareSearch("xiaou").addAggregation(aggregationBuilder).execute().actionGet();
			Filter aggregation = response.getAggregations().get("filter");
			System.out.println(aggregation.getDocCount());
		}
	//多filter
		@Test
		public void test7() {
			
			KeyedFilter keyedFilter1 = new FiltersAggregator.KeyedFilter("price", QueryBuilders.termsQuery("price", "60"));
			KeyedFilter keyedFilter2 = new FiltersAggregator.KeyedFilter("price", QueryBuilders.termsQuery("title", "oo"));
			AggregationBuilder aggregationBuilder = AggregationBuilders.filters("filters",keyedFilter1,keyedFilter2 );
			
			SearchResponse response = client.prepareSearch("xiaou").addAggregation(aggregationBuilder).get();
			Filters filters = response.getAggregations().get("filters");
			for(Filters.Bucket entry : filters.getBuckets()) {
				System.out.println(entry.getKey()+":"+entry.getDocCount());
			}
		}
	// range 范围统计
		@Test
		public void test8() {
			AggregationBuilder aggregationBuilder = AggregationBuilders.range("range")
											        .field("price")
											        .addUnboundedFrom(50)//(,TO)
											        .addRange(30,50)//[from,to)
											        .addUnboundedTo(30);
			SearchResponse response = client.prepareSearch("xiaou").addAggregation(aggregationBuilder).get();
			Range range = response.getAggregations().get("range");
			for(Range.Bucket entry : range.getBuckets()) {
				System.out.println(entry.getKey()+":"+entry.getDocCount());
			}
		}
	// missing 查询有几个null值
		@Test
		public void test9() {
			AggregationBuilder aggregationBuilder = AggregationBuilders.missing("missing").field("price");
			SearchResponse response = client.prepareSearch("xiaou").addAggregation(aggregationBuilder).get();
			Missing missing = response.getAggregations().get("missing");
			System.out.println(missing.getDocCount());
		}
	
	
}
